{-# OPTIONS -Wall #-}

--------------------------------------------------------------------------------
-- |
-- Module      :  Majalan.Base.Internal.Utils
-- Copyright   :  (c) Stephen Tetley 2014
-- License     :  BSD3
--
-- Maintainer  :  stephen.tetley@gmail.com
-- Stability   :  unstable
-- Portability :  GHC
--
-- Hughes lists...
--
-- None of the code in this module should be exposed to clients.
-- 
--------------------------------------------------------------------------------

module Majalan.Base.Internal.Utils
  ( 

  -- * Hughes list
    H
  , emptyH
  , appendH
  , consH
  , snocH
  , wrapH
  , replicateH
  , toListH
  , fromListH

  -- * Hughes Map
  , HMap
  , emptyHMap
  , singletonHMap
  , insertHMap
  , appendHMap
  , toMapH  
  , fromMapH

  )  where



import qualified Data.Map as M

--------------------------------------------------------------------------------
-- Hughes list


type H a = [a] -> [a]

emptyH :: H a 
emptyH = id

appendH :: H a -> H a -> H a
appendH f g = f . g

wrapH :: a -> H a 
wrapH a = (a:)

consH :: a -> H a -> H a
consH a f = (a:) . f

snocH :: H a -> a -> H a
snocH f a = f . (a:)

replicateH :: Int -> a -> H a
replicateH i a = fromListH $ replicate i a


toListH :: H a -> [a]
toListH f = f $ []

fromListH :: [a] -> H a
fromListH xs = (xs++)


--------------------------------------------------------------------------------
-- H Map

-- We want a Map that supports efficient insert and concat...

type HMap k v = M.Map k v -> M.Map k v

emptyHMap :: HMap k v
emptyHMap = id


singletonHMap :: Ord k => k -> v  -> HMap k v 
singletonHMap k v  = M.insert k v


insertHMap :: Ord k => k -> v -> HMap k v -> HMap k v
insertHMap k v f = (M.insert k v) . f


appendHMap :: HMap k v -> HMap k v -> HMap k v
appendHMap f g = f . g



toMapH :: Ord k => HMap k v -> M.Map k v
toMapH f = f $ M.empty


fromMapH :: Ord k => M.Map k v -> HMap k v
fromMapH m = (M.union m)
